package com.example.zhunongzonghe.service.impl;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.zhunongzonghe.beans.ZnCollectPostBean;
import com.example.zhunongzonghe.beans.ZnExchangePostBean;
import com.example.zhunongzonghe.dao.ZnCollectPostMapper;
import com.example.zhunongzonghe.dao.ZnExchangePostMapper;
import com.example.zhunongzonghe.entity.ZnCollectPost;
import com.example.zhunongzonghe.entity.ZnExchangePost;
import com.example.zhunongzonghe.entity.ZnUsers;
import com.example.zhunongzonghe.enums.PostCollectStatusEnum;
import com.example.zhunongzonghe.service.IZnExchangeCommentService;
import com.example.zhunongzonghe.service.IZnUsersService;
import com.example.zhunongzonghe.service.ZnCollectPostService;
import com.example.zhunongzonghe.service.ZnPostLikeService;
import com.example.zhunongzonghe.utils.BeanCopyUtils;
import com.example.zhunongzonghe.utils.RedisCache;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
* @author 蔡某人
* @description 针对表【zn_collect_post】的数据库操作Service实现
* @createDate 2024-04-09 23:56:42
*/
@Service
public class ZnCollectPostServiceImpl extends ServiceImpl<ZnCollectPostMapper, ZnCollectPost>
    implements ZnCollectPostService{

    @Resource
    private RedisCache redisCache;
    @Resource
    private ZnExchangePostMapper znExchangePostMapper;
    @Resource
    private ZnCollectPostMapper znCollectPostMapper;
    @Resource
    private IZnUsersService znUsersService;
    @Resource
    private IZnExchangeCommentService znExchangeCommentService;
    @Resource
    ZnPostLikeService znPostLikeService;


    private static final String POST_COLLECT_KEY = "post_collect";//hash前缀
    private static final String POST_COLLECT_COUNT_KEY = "post_collect_count";//收藏总数前缀
    private static final String POST_COLLECT_DETAIL_KEY = "post_collect_detail";//收藏状态前缀

    @Override
    public void addCollect(ZnCollectPostBean znCollectPostBean, String userName) {
        ZnUsers znUsers = znUsersService.getUserName(userName);
        Integer postId = znCollectPostBean.getPostId();
        Integer userId = znUsers.getId();
        Integer status = znCollectPostBean.getCollectStatus();
        //与redis做交互的Hash的key
        String collectHashKey = collectHashKey(postId.toString(),userId.toString());
        redisCache.setCacheHashValue(POST_COLLECT_KEY,collectHashKey,status);
        String detailKey = POST_COLLECT_DETAIL_KEY+"."+postId+"."+userId;//被谁收藏过的key
        String countKey = POST_COLLECT_COUNT_KEY+"."+postId;
        if (PostCollectStatusEnum.COLLECT.getCode() == status){
            redisCache.increment(countKey,1);//收藏时加1
            redisCache.setCacheObject(detailKey,"1");
        }else {
            Integer count =redisCache.getInt(countKey);
            if (Objects.isNull(count) || count<0){
                return;
            }
            redisCache.increment(countKey,-1);//取消收藏时-1
            redisCache.deleteObject(detailKey);
        }
    }

    @Override
    public Boolean isCollect(Integer postId, Integer userId) {
        String detailKey = POST_COLLECT_DETAIL_KEY+"."+postId+"."+userId;//被谁点过收藏的key
        return redisCache.exist(detailKey);//获取redis内的detailKey，如果存在说明当前用户收藏过该帖子
    }

    @Override
    public Integer CollectCounts(Integer postId) {
        String countKey = POST_COLLECT_COUNT_KEY+"."+postId;
        Integer count =redisCache.getInt(countKey);
        if (Objects.isNull(count) || count<0){
            return 0;
        }
        return redisCache.getInt(countKey);
    }

    @Override
    public void syncPostCollect() {
        Map<Object,Object> postCollectMap = redisCache.getHashAndDelete(POST_COLLECT_KEY);
        if (MapUtil.isEmpty(postCollectMap)){
            return;
        }
        //批量同步到数据库
        List<ZnCollectPost> znCollectPostList = new ArrayList<>();
        postCollectMap.forEach((key,value) ->{
            ZnCollectPost znCollectPost = new ZnCollectPost();
            String[] keyArr = key.toString().split(":");
            String postId = keyArr[0];
            String UserId = keyArr[1];
            znCollectPost.setPostId(Integer.valueOf(postId));
            znCollectPost.setUserId(Integer.valueOf(UserId));
            znCollectPost.setCollectStatus((Integer) value);
            znCollectPost.setCreateTime(LocalDateTime.now());
            znCollectPost.setUpdateTime(LocalDateTime.now());
            znCollectPostList.add(znCollectPost);
        });
        znCollectPostMapper.insertList(znCollectPostList);
    }

    @Override
    public void delRepetition() {
        znCollectPostMapper.delRepetition();
    }

    @Override
    public Page<ZnCollectPostBean> getMyCollect(String userName,Integer currentPage,Integer pageSize) {
        ZnUsers znUsers = znUsersService.getUserName(userName);
        Page<ZnCollectPost> page = new Page<>(currentPage,pageSize);
        LambdaQueryWrapper<ZnCollectPost> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ZnCollectPost::getUserId,znUsers.getId()).eq(ZnCollectPost::getCollectStatus,1);
        Page<ZnCollectPost> collectPostPage = znCollectPostMapper.selectPage(page,queryWrapper);
        Page<ZnCollectPostBean> collPageBean = BeanCopyUtils.copyBeanPage(collectPostPage,ZnCollectPostBean.class);
        for (ZnCollectPostBean collect: collPageBean.getRecords()
             ) {
            LambdaQueryWrapper<ZnExchangePost> postLambda = new LambdaQueryWrapper<>();
            postLambda.eq(ZnExchangePost::getPostId,collect.getPostId());
            ZnExchangePost znExchangePost = znExchangePostMapper.selectOne(postLambda);
            if (znExchangePost!=null){
                ZnExchangePostBean postBean = BeanCopyUtils.copyBean(znExchangePost,ZnExchangePostBean.class);
                ZnUsers users = znUsersService.getById(postBean.getUserId());
                postBean.setAvatar(users.getAvatar());
                postBean.setNickName(users.getNickname());
                postBean.setCommentNumBer(znExchangeCommentService.CommentNumBer(collect.getPostId()));
                postBean.setLinked(znPostLikeService.isLiked(collect.getPostId(),znUsers.getId()));
                postBean.setLikeCount(znPostLikeService.likeCounts(collect.getPostId()));
                postBean.setCollectOrNot(isCollect(collect.getPostId(),znUsers.getId()));
                postBean.setCollectCount(CollectCounts(collect.getPostId()));
                collect.setPosts(postBean);
            }else {
                return null;
            }
        }
        return collPageBean;
    }

    @Override
    public void updateStatus(ZnCollectPost znCollectPost) {
        Integer status = znCollectPost.getCollectStatus();
        Integer postId = znCollectPost.getPostId();
        Integer userId = znCollectPost.getUserId();
        //与redis做交互的Hash的key
        String collectHashKey = collectHashKey(znCollectPost.getPostId().toString(),znCollectPost.getUserId().toString());
        redisCache.setCacheHashValue(POST_COLLECT_KEY,collectHashKey,status);
        String detailKey = POST_COLLECT_DETAIL_KEY+"."+postId+"."+userId;//被谁点过赞的key
        String countKey = POST_COLLECT_COUNT_KEY+"."+postId;
        if (PostCollectStatusEnum.UN_COLLECT.getCode() == status){
            Integer count =redisCache.getInt(countKey);
            if (Objects.isNull(count) || count<0){
                return;
            }
            redisCache.increment(countKey,-1);//取消收藏时-1
            redisCache.deleteObject(detailKey);
        }
        znCollectPost.setUpdateTime(LocalDateTime.now());
        znCollectPostMapper.updateById(znCollectPost);
    }

    @Override
    public Page<ZnExchangePostBean> MyCollects(String userName, Integer currentPage, Integer pageSize) {
        ZnUsers znUsers = znUsersService.getUserName(userName);
        String key = POST_COLLECT_DETAIL_KEY+"*"+znUsers.getId();
        Collection<String> keys = redisCache.keys(key);
        if (keys==null) return null;
        List<ZnExchangePostBean> beanList = new ArrayList<>();
        for (String stringKey: keys
             ) {
            String[] parts = stringKey.split("\\."); // 使用 "." 分割字符串
            String postId = parts[1]; // 第二部分即为 "21"
            Page<ZnExchangePost> page = new Page<>(currentPage,pageSize);
            LambdaQueryWrapper<ZnExchangePost> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ZnExchangePost::getPostId,postId);
            Page<ZnExchangePost> postPage = znExchangePostMapper.selectPage(page,queryWrapper);
            for (ZnExchangePost znpost: postPage.getRecords()
            ) {
                ZnExchangePostBean postBean = new ZnExchangePostBean();
                ZnUsers usersBean = znUsersService.getById(znpost.getUserId());
                postBean.setNickName(usersBean.getNickname());
                postBean.setAvatar(usersBean.getAvatar());
                postBean.setCommentNumBer(znExchangeCommentService.CommentNumBer(znpost.getPostId()));
                postBean.setLinked(znPostLikeService.isLiked(znpost.getPostId(),znUsers.getId()));
                postBean.setLikeCount(znPostLikeService.likeCounts(znpost.getPostId()));
                postBean.setCollectOrNot(isCollect(znpost.getPostId(),znUsers.getId()));
                postBean.setCollectCount(CollectCounts(znpost.getPostId()));
                BeanUtils.copyProperties(znpost,postBean);
                beanList.add(postBean);
            }
        }
        Page<ZnExchangePostBean> resultPage = new Page<>();
        resultPage.setRecords(beanList);
        resultPage.setSize(beanList.size());
        resultPage.setTotal(beanList.size());
        resultPage.setCurrent(currentPage);
        return resultPage;
    }


    private String collectHashKey(String postId,String userId){
        return postId + ":" +userId;
    }
}




